package com.practice.config;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.ContentCachingRequestWrapper;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

@Slf4j
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private static final List<String> EXCLUDE_URLS = Arrays.asList(
            "/jiojio/auth/login",
            "/actuator/health"
    );

    private final JwtUtils jwtUtils;

    public JwtAuthenticationFilter(JwtUtils jwtUtils) {
        this.jwtUtils = jwtUtils;
    }

    @Override
    protected void doFilterInternal(
            HttpServletRequest request,
            HttpServletResponse response,
            FilterChain filterChain
    ) throws ServletException, IOException {

        // 提前包装请求对象（关键修复点）
        ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request);

        try {
            // 设置CORS响应头（必须最先执行）
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "*");
            response.setHeader("Access-Control-Max-Age", "3600");

            // 排除路径检查（使用包装后的request）
            if (EXCLUDE_URLS.contains(requestWrapper.getRequestURI())) {
                filterChain.doFilter(requestWrapper, response);
                return;
            }

            // JWT认证逻辑（使用包装后的request）
            String token = parseToken(requestWrapper);
            if (token != null && jwtUtils.validateToken(token)) {
                String username = jwtUtils.getUsername(token);
                UsernamePasswordAuthenticationToken authentication =
                        new UsernamePasswordAuthenticationToken(username, null, null);
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }

            // 统一使用包装后的request继续过滤器链（关键修复点）
            filterChain.doFilter(requestWrapper, response);

        } finally {
            // 日志记录（必须在doFilter之后执行）
            if (!EXCLUDE_URLS.contains(requestWrapper.getRequestURI())) {
                byte[] body = requestWrapper.getContentAsByteArray();
                log.info("接收请求:{},请求体:{}", requestWrapper.getRequestURI(), new String(body));
            }
        }
    }

    private String parseToken(HttpServletRequest request) {
        String header = request.getHeader("Authorization");
        if (StringUtils.hasText(header) && header.startsWith("Bearer ")) {
            return header.substring(7);
        }
        return null;
    }
}